﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Net;
using Newtonsoft.Json;
using System.IO;

namespace nTribeHR
{
    public class TribeHRLeaveRequestService : TribeHRServiceBase
    {
        private TribeHRConnection tribeHRConnection { get; set; }

        public TribeHRLeaveRequestService(TribeHRConnection tribeHRConnection)
        {
            this.tribeHRConnection = tribeHRConnection;
        }

        private TribeHRLeaveRequestService()
        { }

        public LeaveRequest GetLeaveRequestById(int id)
        {
            XmlDocument xdoc = LoadLeaveRequestXmlDocumentForUrl("/leave_requests/" + id.ToString() + ".xml");
            return MapXmlLeaveRequestToLeaveRequest(xdoc);
        }

        public List<LeaveRequest> ListPendingLeaveRequests()
        {
            XmlDocument xdoc = LoadLeaveRequestXmlDocumentForUrl("/leave_requests/pending.xml");
            return MapXmlLeaveRequestsToLeaveRequests(xdoc);
        }

        public List<LeaveRequest> ListApprovedLeaveRequests()
        {
            XmlDocument xdoc = LoadLeaveRequestXmlDocumentForUrl("/leave_requests/approved.xml");
            return MapXmlLeaveRequestsToLeaveRequests(xdoc);
        }

        public List<LeaveRequest> ListRejectedLeaveRequests()
        {
            XmlDocument xdoc = LoadLeaveRequestXmlDocumentForUrl("/leave_requests/rejected.xml");
            return MapXmlLeaveRequestsToLeaveRequests(xdoc);
        }

        public List<LeaveRequest> ListAllLeaveRequests()
        {
            XmlDocument xdoc = LoadLeaveRequestXmlDocumentForUrl("/leave_requests/all.xml");
            return MapXmlLeaveRequestsToLeaveRequests(xdoc);
        }

        public void AddNewLeaveRequest()
        {
            PostNewLeaveRequest(null);
        }

        private LeaveRequest MapXmlLeaveRequestToLeaveRequest(XmlDocument leaveRequestXmlDoc)
        {
            LeaveRequest leaveRequest = new LeaveRequest();
            return MapXmlLeaveRequestNodeToLeaveRequest(leaveRequestXmlDoc.SelectSingleNode("/leave_request/leave_request"));
        }

        private List<LeaveRequest> MapXmlLeaveRequestsToLeaveRequests(XmlDocument leaveRequestXmlDoc)
        {
            List<LeaveRequest> leaveRequests = new List<LeaveRequest>();

            XmlNode leaveRequestNode = leaveRequestXmlDoc.SelectSingleNode("/leave_requests");

            XmlNodeList leaveRequestNodes = leaveRequestNode.SelectNodes("leave_request");

            foreach (XmlNode node in leaveRequestNodes)
            {
                leaveRequests.Add(MapXmlLeaveRequestNodeToLeaveRequest(node));
            }

            return leaveRequests;
        }

        private LeaveRequest MapXmlLeaveRequestNodeToLeaveRequest(XmlNode leaveRequestNode)
        {
            LeaveRequest leaveRequest = new LeaveRequest();
            using (ParseResultStopwatch = Utilities.DisposableStopwatch.StartNew())
            {

                leaveRequest.MessageToManager = leaveRequestNode.Attributes.GetNamedItem("comments").Value;
                leaveRequest.StartDate = Convert.ToDateTime(leaveRequestNode.Attributes.GetNamedItem("date_start").Value);
                leaveRequest.EndDate = Convert.ToDateTime(leaveRequestNode.Attributes.GetNamedItem("date_end").Value);
                leaveRequest.TotalDaysOffWork = Convert.ToDouble(leaveRequestNode.Attributes.GetNamedItem("days").Value);
                leaveRequest.Status = (LeaveStatus)Enum.Parse(typeof(LeaveStatus), leaveRequestNode.Attributes.GetNamedItem("status").Value);

                XmlNode leaveTypeNode = leaveRequestNode.SelectSingleNode("leave_type");
                leaveRequest.TypeOfTimeOff = leaveTypeNode.Attributes.GetNamedItem("name").Value;

                XmlNode userTypeNode = leaveRequestNode.SelectSingleNode("user");
                leaveRequest.EmployeeName = userTypeNode.Attributes.GetNamedItem("full_name").Value;
                leaveRequest.EmployeeEmail = userTypeNode.Attributes.GetNamedItem("email").Value;
            }

            return leaveRequest;
        }

        private XmlDocument LoadLeaveRequestXmlDocumentForUrl(string url)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tribeHRConnection.ConnectUrl + url);
            request.Credentials = new NetworkCredential(tribeHRConnection.Username, tribeHRConnection.ApiKey);

            using (WebRequestStopwatch = Utilities.DisposableStopwatch.StartNew())
            {
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    WebRequestStopwatch.Stop();
                    XmlDocument xdoc = new XmlDocument();
                    using (LoadXmlStopwatch = Utilities.DisposableStopwatch.StartNew())
                    {
                        xdoc.Load(response.GetResponseStream());
                    }

                    return xdoc;
                }
            }
        }

        private void PostNewLeaveRequest(LeaveRequest leaveRequest)
        {
            // STILL WORKING ON THIS!!!!!

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tribeHRConnection.ConnectUrl + "/leave_requests.xml");
            request.Credentials = new NetworkCredential(tribeHRConnection.Username, tribeHRConnection.ApiKey);
            request.Method = "POST";

            string postData = "leave_type_id=2&user_id=5&comments=TEST&date_start=10/6/2012&date_end=10/7/2012&status=0&days=2";

            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";
            // Set the ContentLength property of the WebRequest.
            request.ContentLength = byteArray.Length;
            // Get the request stream.
            Stream dataStream = request.GetRequestStream();
            // Write the data to the request stream.
            dataStream.Write(byteArray, 0, byteArray.Length);
            // Close the Stream object.
            dataStream.Close();
            // Get the response.
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            // Display the status.
            Console.WriteLine(((HttpWebResponse)response).StatusDescription);
            // Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);
            // Read the content.
            string responseFromServer = reader.ReadToEnd();
            // Display the content.
            Console.WriteLine(responseFromServer);
            // Clean up the streams.
            reader.Close();
            dataStream.Close();
            response.Close();
        }
    }
}
